package com.fastbee.web.controller.bigScreen;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSONObject;
import com.fastbee.common.core.controller.BaseController;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fastbee.common.core.domain.AjaxResult;
import com.fastbee.common.core.domain.R;
import com.fastbee.common.core.mq.InvokeReqDto;
import com.fastbee.common.core.mq.InvokeReqSimpleDto;
import com.fastbee.common.core.page.TableDataInfo;
import com.fastbee.common.utils.StringUtils;
import com.fastbee.iot.data.service.IFunctionInvoke;
import com.fastbee.iot.domain.*;
import com.fastbee.iot.model.BigScreenAlarmStatisVo;
import com.fastbee.iot.model.CommonStatisVo;
import com.fastbee.iot.model.DeviceAndProductVo;
import com.fastbee.iot.model.SmartDevicesVo;
import com.fastbee.iot.service.IAlertLogService;
import com.fastbee.iot.service.IDeviceService;
import com.fastbee.iot.service.IProductService;
import com.fastbee.iot.tdengine.service.ILogService;
import com.fastbee.system.domain.CommonStatistics;
import com.fastbee.system.domain.SysConfig;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Api(tags = "大屏设备信息管理模块")
@RestController
@RequestMapping("/bigScreen/device")
public class BigScreenDeviceController extends BaseController {
    @Autowired
    private IDeviceService deviceService;

    @Autowired
    private IAlertLogService alertLogService;

    @Autowired
    private IProductService productService;

    @Autowired
    private IFunctionInvoke functionInvoke;

    @Resource
    private ILogService logService;

    /**
     * 获取设备接入统计信息
     */
    @ApiOperation("获取设备接入统计信息")
    @PostMapping("/in/statistics")
    public R<List<CommonStatisVo>> deviceStatistics(@RequestBody CommonStatistics dto)
    {
        List<CommonStatisVo> resultList = new LinkedList<>();
        List<Product> productList = productService.getAllProduct(dto);
        if(productList.size() == 0){
            return R.ok(resultList);
        }
        Device device = new Device();
        List<Device> deviceList = deviceService.selectDeviceList(device);
        Map<String,List<Device>> deviceMap = new HashMap<>();
        if(deviceList.size() > 0){
            deviceMap = deviceList.stream().collect(Collectors.groupingBy(Device::getProductName));
        }
        for (Product product : productList) {
            CommonStatisVo vo = new CommonStatisVo();
            vo.setName(product.getProductName());
            vo.setValue(deviceMap.get(product.getProductName()) != null ? new BigDecimal(deviceMap.get(product.getProductName()).size()) : BigDecimal.ZERO);
            resultList.add(vo);
        }
        return R.ok(resultList);
    }

    /**
     * 获取告警分页
     */
    @ApiOperation("获取告警分页")
    @PostMapping("/alarm/page")
    public R<Page<AlertLogEntity>> getBigAlarmPage(@RequestBody AlertLogPageDto dto)
    {
        Page<AlertLogEntity> alertPage = alertLogService.getBigAlarmPage(dto);
        for (AlertLogEntity record : alertPage.getRecords()) {
            if(record.getCreateTime() != null){
                record.setCreateTime(DateUtil.offsetHour(record.getCreateTime(),16));
            }
        }
        return R.ok(alertPage);
    }

    /**
     * 告警数据处理
     */
    @ApiOperation("告警数据处理")
    @PostMapping("/alarm/handle")
    public R alarmUpdate(@RequestBody AlertLog dto)
    {
        alertLogService.updateAlertLogStatus(dto);
        return R.ok();
    }

    /**
     * 获取告警管理统计信息
     */
    @ApiOperation("获取告警管理统计信息")
    @PostMapping("/alarm/statistics")
    public R<BigScreenAlarmStatisVo> getBigScreenAlarmStatisVo(@RequestBody CommonStatistics dto)
    {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(DateUtil.offsetHour(new Date(),16));
        Integer year = calendar.get(Calendar.YEAR);
        Integer month = calendar.get(Calendar.MONTH)+1;
        Integer day = calendar.get(Calendar.DAY_OF_MONTH)+1;
        Integer lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

        if(dto.getTypeId() != null){
            if(dto.getTypeId() == 1){
                dto.setStartDate(year+"-01-01 00:00:00");
                dto.setEndDate(year+"-12-31 23:59:59");
            }
            if(dto.getTypeId() == 2){
                dto.setStartDate(year+"-"+month+"-01"+" 00:00:00");
                dto.setEndDate(year+"-"+month+"-"+lastDay+" 23:59:59");
            }
            if(dto.getTypeId() == 3){
                int dayData = day;
                if(dayData > 1){
                    dayData = (dayData -1);
                }
                dto.setStartDate(year+"-"+month+"-"+dayData+" 00:00:00");
                dto.setEndDate(year+"-"+month+"-"+day+" 23:59:59");
            }
        }
        BigScreenAlarmStatisVo statisVo = alertLogService.getBigScreenAlarmStatisVo(dto);
        return R.ok(statisVo);
    }

    /**
     * 智能设备
     */
    @ApiOperation("智能设备")
    @PostMapping("/smartDevices")
    public R selectSmartDevices(@RequestBody CommonStatistics dto){
        SmartDevicesVo smartDevicesVo = new SmartDevicesVo();

        Map<String,List<Device>> deviceMap = new HashMap<>();
        Device device = new Device();
        if(null != dto.getAddressId()){
            device.setAddressId(dto.getAddressId());
        }
        device.setOutProductId(1012L);
        List<Device> deviceList = deviceService.selectDeviceList(device);
        if(null != deviceList && deviceList.size()>0){
            smartDevicesVo.setDeviceTotal(deviceList.size());
            Integer deviceNormal = deviceList.stream().filter(d->d.getStatus().equals(3)).collect(Collectors.toList()).size();
            smartDevicesVo.setDeviceNormal(deviceNormal);
            Integer deviceActive = deviceList.stream().filter(d->d.getStatus().equals(1)).collect(Collectors.toList()).size();
            smartDevicesVo.setDeviceActive(deviceActive);
            Integer deviceOffLine = deviceList.stream().filter(d->d.getStatus().equals(4)).collect(Collectors.toList()).size();
            smartDevicesVo.setDeviceOffLine(deviceOffLine);

            deviceMap = deviceList.stream().collect(Collectors.groupingBy(Device::getProductName));
        }

        List<Product> productList = productService.selectAllProduct();
        if(null != productList && productList.size()>0){
            for (Product product : productList) {
                DeviceAndProductVo deviceAndProductVo = new DeviceAndProductVo();
                deviceAndProductVo.setName(product.getProductName());
                deviceAndProductVo.setTotalValue(deviceMap.get(product.getProductName()) != null ? deviceMap.get(product.getProductName()).size() : 0);
                deviceAndProductVo.setOnlineTotalValue(deviceMap.get(product.getProductName()) != null ? deviceMap.get(product.getProductName()).stream().filter(d->d.getStatus().equals(3)).collect(Collectors.toList()).size() : 0);
                smartDevicesVo.getDeviceAndProductVos().add(deviceAndProductVo);
            }
        }
        return R.ok(smartDevicesVo);
    }

    /**
     * 服务下发返回回执
     */
    @PostMapping(value = "/service/invokeReply")
    @ApiOperation(value = "服务下发返回回执")
    public R invokeReply(@Valid @RequestBody InvokeReqDto reqDto) {
        reqDto.setParams(new JSONObject(reqDto.getRemoteCommand()));
        functionInvoke.invokeReply(reqDto);
        return R.ok();
    }

    /**
     * 智能设备清单
     */
    @ApiOperation("智能设备清单")
    @PostMapping("/smartDevicesDetail")
    public R<Page<Device>> selectSmartDevicesDetail(@RequestBody CommonStatistics dto){
        Device device = new Device();
        if(null != dto.getAddressId()){
            device.setAddressId(dto.getAddressId());
        }
        if(null != dto.getProductId()){
            device.setProductId(dto.getProductId());
        }
        if(dto.getOutProductId() == null){
            dto.setOutProductId(1012L);
        }
        Page<Device> deviceList = deviceService.selectDevicePage(dto);
        for (Device record : deviceList.getRecords()) {
            String number = record.getSerialNumber();
            if(StringUtils.isBlank(number)){
                continue;
            }
            if(record.getProductId() == null){
                continue;
            }
            if(record.getProductId() == 1011L){
                //电表
                String status = logService.getLeastDeviceData(number,"ActiveEnergy");
                record.setCurrentEle(status);
                continue;
            }
            if(record.getProductId() == 1010L){
                String status = logService.getLeastDeviceData(number,"ActiveEnergy");
                record.setCurrentEle(status);
            }else{
                String status = logService.getLeastDeviceData(number,"ele");
                if(StringUtils.isNotBlank(status)){
                    record.setCurrentEle(status.split("/")[2]);
                }
            }

            if(record.getProductId() == 1010L){
                //空开
                String status = logService.getLeastDeviceData(number,"GateState");
                if(StringUtils.isNotBlank(status) && StringUtils.equals(status,"true")){
                    record.setGateState(1);
                }
            }else if(record.getProductId() == 1001L || record.getProductId() == 1004L){
                //插座、单开
                String status = logService.getLeastDeviceData(number,"smart");
                JSONObject jsonObject = new JSONObject();
                if(StringUtils.isNotBlank(status)){
                    jsonObject.put("第一个",status.substring(0,1));
                }else{
                    jsonObject.put("第一个",0);
                }
                record.setSmartState(jsonObject);
            }else if(record.getProductId() == 1002L){
                //双开
                String status = logService.getLeastDeviceData(number,"smart");
                JSONObject jsonObject = new JSONObject();
                if(StringUtils.isNotBlank(status)){
                    jsonObject.put("第一个",status.substring(0,1));
                    jsonObject.put("第二个",status.substring(1,2));
                }else{
                    jsonObject.put("第一个",0);
                    jsonObject.put("第二个",0);
                }
                record.setSmartState(jsonObject);
            }else if(record.getProductId() == 1003L){
                //三开
                String status = logService.getLeastDeviceData(number,"smart");
                JSONObject jsonObject = new JSONObject();
                if(StringUtils.isNotBlank(status)){
                    jsonObject.put("第一个",status.substring(0,1));
                    jsonObject.put("第二个",status.substring(1,2));
                    jsonObject.put("第三个",status.substring(2,3));
                }else{
                    jsonObject.put("第一个",0);
                    jsonObject.put("第二个",0);
                    jsonObject.put("第三个",0);
                }
                record.setSmartState(jsonObject);
            }
        }
        return R.ok(deviceList);
    }

    /**
     * 获取设备上传数据信息
     */
    @ApiOperation("获取设备上传数据信息")
    @GetMapping("/getDeviceData")
    public R<DeviceEl> getDeviceData(@RequestParam(value = "serialNumber") String serialNumber){
        Device device = deviceService.getDeviceInfo(serialNumber);
        if(device == null){
            return R.fail("设备信息异常");
        }
        if(device.getProductId() == null){
            return R.fail("设备类型异常");
        }
        DeviceEl resultData = new DeviceEl();
        resultData.setSerialNumber(serialNumber);
        if(device.getProductId() == 1010L){
            String voltage = logService.getLeastDeviceData(serialNumber,"Voltage");
            String current = logService.getLeastDeviceData(serialNumber,"Current");
            String activePower = logService.getLeastDeviceData(serialNumber,"ActivePower");
            resultData.setVoltage(new BigDecimal(voltage));
            resultData.setCurrent(new BigDecimal(current));
            resultData.setActivePower(new BigDecimal(activePower));
            String status = logService.getLeastDeviceData(serialNumber,"GateState");
            if(StringUtils.isNotBlank(status) && StringUtils.equals(status,"true")){
                resultData.setGateState(1);
            }
        }else if(device.getProductId() == 1001L || device.getProductId() == 1004L){
            //插座、单开
            String ele = logService.getLeastDeviceData(serialNumber,"ele");
            if(StringUtils.isNotBlank(ele)){
                String[] eleAr = ele.split("/");
                BigDecimal voltage = new BigDecimal(eleAr[0]);
                BigDecimal current = new BigDecimal(eleAr[1]);
                BigDecimal activePower = voltage.multiply(current).setScale(2, RoundingMode.HALF_UP);
                resultData.setVoltage(voltage);
                resultData.setCurrent(current);
                resultData.setActivePower(activePower);
            }

            String status = logService.getLeastDeviceData(serialNumber,"smart");
            JSONObject jsonObject = new JSONObject();
            if(StringUtils.isNotBlank(status)){
                jsonObject.put("第一个",status.substring(0,1));
            }else{
                jsonObject.put("第一个",0);
            }
            resultData.setSmartState(jsonObject);
        }else if(device.getProductId() == 1002L){
            //双开
            String ele = logService.getLeastDeviceData(serialNumber,"ele");
            if(StringUtils.isNotBlank(ele)){
                String[] eleAr = ele.split("/");
                BigDecimal voltage = new BigDecimal(eleAr[0]);
                BigDecimal current = new BigDecimal(eleAr[1]);
                BigDecimal activePower = voltage.multiply(current).setScale(2, RoundingMode.HALF_UP);
                resultData.setVoltage(voltage);
                resultData.setCurrent(current);
                resultData.setActivePower(activePower);
            }
            String status = logService.getLeastDeviceData(serialNumber,"smart");
            JSONObject jsonObject = new JSONObject();
            if(StringUtils.isNotBlank(status)){
                jsonObject.put("第一个",status.substring(0,1));
                jsonObject.put("第二个",status.substring(1,2));
            }else{
                jsonObject.put("第一个",0);
                jsonObject.put("第二个",0);
            }
            resultData.setSmartState(jsonObject);
        }else if(device.getProductId() == 1003L){
            //三开
            String ele = logService.getLeastDeviceData(serialNumber,"ele");
            if(StringUtils.isNotBlank(ele)){
                String[] eleAr = ele.split("/");
                BigDecimal voltage = new BigDecimal(eleAr[0]);
                BigDecimal current = new BigDecimal(eleAr[1]);
                BigDecimal activePower = voltage.multiply(current).setScale(2, RoundingMode.HALF_UP);
                resultData.setVoltage(voltage);
                resultData.setCurrent(current);
                resultData.setActivePower(activePower);
            }
            String status = logService.getLeastDeviceData(serialNumber,"smart");
            JSONObject jsonObject = new JSONObject();
            if(StringUtils.isNotBlank(status)){
                jsonObject.put("第一个",status.substring(0,1));
                jsonObject.put("第二个",status.substring(1,2));
                jsonObject.put("第三个",status.substring(2,3));
            }else{
                jsonObject.put("第一个",0);
                jsonObject.put("第二个",0);
                jsonObject.put("第三个",0);
            }
            resultData.setSmartState(jsonObject);
        }
        return R.ok(resultData);
    }
}
